import base64
import json
import logging
import re

from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
from django.utils.translation import ugettext as _
from rest_framework import authentication
from rest_framework import exceptions
from rest_framework_jwt.authentication import (
    JSONWebTokenAuthentication as CoreJSONWebTokenAuthentication,
)
from rest_framework_jwt.settings import api_settings
from rest_framework_jwt.utils import jwt_decode_handler

jwt_decode_handler = api_settings.JWT_DECODE_HANDLER
jwt_get_username_from_payload = api_settings.JWT_PAYLOAD_GET_USERNAME_HANDLER
User = get_user_model()

LOG = logging.getLogger(__name__)


class JSONWebTokenAuthentication(CoreJSONWebTokenAuthentication):
    @staticmethod
    def _get_or_create_user(user_id, payload=None):
        if payload is None:
            payload = {}

        user, _ = User.objects.get_or_create(
            id=user_id, username=user_id, defaults={"password": user_id}
        )

        return user

    def authenticate_credentials(self, payload):
        """
        Returns an active user that matches the payload's user id and email.
        """
        username = jwt_get_username_from_payload(payload)

        if not username:
            msg = _("Invalid payload.")
            raise exceptions.AuthenticationFailed(msg)

        user = self._get_or_create_user(username, payload)

        if not user.is_active:
            msg = _("User account is disabled.")
            raise exceptions.AuthenticationFailed(msg)

        return user


class JWTAuthentication(authentication.BaseAuthentication):
    def has_permission(self, request, view):
        token = request.META.get("HTTP_TOKEN", None)
        if token is None:
            return None

        token = jwt_decode_handler(token)

        username = token.get("username", None)
        user_id = token.get("user_id", None)

        if (username is None) or (user_id is None):
            return None
        try:
            user = User.objects.get(username=username, id=user_id)
        except:
            return False

        return True


class ShopModelBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):

        if request is None:
            try:
                user = User.objects.get(username=username)
            except Exception as e:
                return None

        try:
            if re.match(r"^1[3-9]\d{9}$", username):

                user = User.objects.get(mobile=username)
            else:
                user = User.objects.get(username=username)
        except:
            return None

        if user.check_password(password):
            return user
        else:
            return None


def jwt_response_payload_handler(token, user=None, request=None):
    """
    自定义jwt认证成功返回数据
    """
    return {"token": token, "id": user.id, "username": user.username}
